package com.arcsoft.commonbase.widgets

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView

class CustomDividerItemDecoration:RecyclerView.ItemDecoration {

    companion object {
        private const val TAG = "DividerItem"
        const val HORIZONTAL = LinearLayout.HORIZONTAL
        const val VERTICAL = LinearLayout.VERTICAL
        private val ATTRS = intArrayOf(android.R.attr.listDivider)
    }


    private var mDividerHeight = 0

    private var mPaint: Paint? = null
    private var mDivider: Drawable? = null

    /**
     * Current orientation. Either [.HORIZONTAL] or [.VERTICAL].
     */
    private var mOrientation = 0

    private val mBounds = Rect()

    constructor(context: Context, orientation: Int) {
        val typedArray = context.obtainStyledAttributes(ATTRS)
        mDivider = typedArray.getDrawable(0)
        if (mDivider == null) {
            Log.w(TAG, "@android:attr/listDivider was not set in the theme used for this "
                    + "DividerItemDecoration. Please set that attribute all call setDrawable()")
        }
        typedArray.recycle()
        setOrientation(orientation)
        mDivider?.let {
            mDividerHeight = it.intrinsicHeight
        }
    }

    constructor(context: Context, orientation: Int, dividerHeight: Int, dividerColor: Int):this(context, orientation) {
        mDividerHeight = dividerHeight
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG).also {
            it.color = dividerColor
            it.style = Paint.Style.FILL
        }
    }

    /**
     * Sets the orientation for this divider. This should be called if
     * [RecyclerView.LayoutManager] changes orientation.
     *
     * @param orientation [.HORIZONTAL] or [.VERTICAL]
     */
    private fun setOrientation(orientation: Int) {
        require(!(orientation != HORIZONTAL && orientation != VERTICAL)) { "Invalid orientation. It should be either HORIZONTAL or VERTICAL" }
        mOrientation = orientation
    }

    /**
     * Sets the [Drawable] for this divider.
     *
     * @param drawable Drawable that should be used as a divider.
     */
    fun setDrawable(drawable: Drawable) {
        mDivider = drawable
    }

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        if (parent.layoutManager == null || mDivider == null) {
            return
        }
        when (mOrientation) {
            VERTICAL -> drawVertical(c, parent)
            HORIZONTAL -> drawHorizontal(c, parent)
        }
    }

    private fun drawVertical(canvas: Canvas, parent: RecyclerView) {
        canvas.save()
        var left = 0
        var right = parent.width

        if (parent.clipToPadding) {
            left = parent.paddingLeft
            right = parent.width - parent.paddingRight
            canvas.clipRect(left, parent.paddingTop, right, parent.height - parent.paddingBottom)
        }

        val childCount = parent.childCount -1
        if (childCount > 0) {
            (0 until childCount).forEach { index ->
                val child = parent.getChildAt(index)
                parent.getDecoratedBoundsWithMargins(child, mBounds)
                val bottom = mBounds.bottom + Math.round(child.translationY)
                val top = bottom - mDividerHeight
                mDivider?.let {
                    it.setBounds(left, top, right, bottom)
                    it.draw(canvas)
                }
                mPaint?.let {
                    canvas.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), it)
                }
            }
        }
        canvas.restore()
    }

    private fun drawHorizontal(canvas: Canvas, parent: RecyclerView) {
        canvas.save()
        var top = 0
        var bottom = parent.height

        if (parent.clipToPadding) {
            top = parent.paddingTop
            bottom = parent.height - parent.paddingBottom
            canvas.clipRect(parent.paddingLeft, top, parent.width - parent.paddingRight, bottom)
        }
        val childCount = parent.childCount
        (0 until childCount).forEach { index ->
            val child = parent.getChildAt(index)
            parent.layoutManager?.getDecoratedBoundsWithMargins(child, mBounds)
            mDivider?.let {
                val right = mBounds.right + Math.round(child.translationX)
                val left = right - it.intrinsicWidth
                it.setBounds(left, top, right, bottom)
                it.draw(canvas)
                mPaint?.let { paint ->
                    canvas.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), paint)
                }
            }
        }
        canvas.restore()
    }

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        if (mDivider == null) {
            outRect.set(0, 0, 0, 0)
            return
        }
        var intrinsicWidth = 0
        mDivider?.let {
            intrinsicWidth = it.intrinsicWidth
        }
        when(mOrientation) {
            VERTICAL -> outRect.set(0, 0, 0, mDividerHeight)
            HORIZONTAL -> outRect.set(0, 0, intrinsicWidth, 0)
        }
    }
}